package com.SingleSeckill.service.impl;


import com.SingleSeckill.dao.UserDOMapper;
import com.SingleSeckill.dao.UserPasswordDOMapper;
import com.SingleSeckill.dataobject.UserDO;
import com.SingleSeckill.dataobject.UserPasswordDO;
import com.SingleSeckill.error.BusinessException;
import com.SingleSeckill.error.EmBusinessError;
import com.SingleSeckill.service.UserService;
import com.SingleSeckill.service.model.UserModel;
import com.SingleSeckill.validator.ValidationResult;
import com.SingleSeckill.validator.ValidatorImpl;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDOMapper userDOMapper;

    @Autowired
    private UserPasswordDOMapper userPasswordDOMapper;

    @Autowired
    private ValidatorImpl validator;

    @Override
    public UserModel getUserById(Integer id) {
        UserDO userDO = userDOMapper.selectByPrimaryKey(id);

        if(userDO == null) {
            return null;
        }
        UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());

        //返回的是Model，完整的核心用户对象
        return convertFromDataObject(userDO, userPasswordDO);
    }

    @Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        //判空
        if(userModel == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }

        ValidationResult result = validator.validationResult(userModel);
        if(result.isHasErrors()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }

        //实现model -> dataObject方法
        UserDO userDO = userDOConvertFromModel(userModel);
        //这里捕获手机号重复出现的异常，将user表中的手机号添加唯一索引，捕获DuplicateKeyException异常
        try {
            Integer id= userDOMapper.insertSelective(userDO);
            userDO.setId(id);
        } catch(DuplicateKeyException ex) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已重复注册");
        }
        userModel.setId(userDO.getId());
        UserPasswordDO userPasswordDO = UserPWDDOConvertFromModel(userModel);
        userPasswordDOMapper.insertSelective(userPasswordDO);
    }

    @Override
    public UserModel validateLogin(String telphone, String encrptPassword) throws BusinessException {
        //通过用户手机获取用户手机
        UserDO userDO = userDOMapper.selectByTelephone(telphone);
        if(userDO == null) {
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }
        UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());
        UserModel userModel = convertFromDataObject(userDO, userPasswordDO);

        //校验用户信息内加密密码是否和传入密码匹配
        if(!StringUtils.equals(encrptPassword, userModel.getPassword())) {
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }

        return userModel;

    }

    private UserDO userDOConvertFromModel(UserModel userModel) {
        if(userModel == null) {
            return null;
        }
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(userModel, userDO);
        return userDO;
    }

    private UserPasswordDO UserPWDDOConvertFromModel(UserModel userModel) {
        if(userModel == null) {
            return null;
        }
        UserPasswordDO userPasswordDO = new UserPasswordDO();
        userPasswordDO.setPassword(userModel.getPassword());
        userPasswordDO.setUserId(userModel.getId());
        return userPasswordDO;
    }


    private UserModel convertFromDataObject(UserDO userDO, UserPasswordDO userPasswordDO) {
        if(userDO == null) {
            return null;
        }
        UserModel userModel = new UserModel();
        BeanUtils.copyProperties(userDO, userModel);
        if(userPasswordDO != null) {
            userModel.setPassword(userPasswordDO.getPassword());
        }
        return userModel;
    }
}

